from enum import Enum
from typing import Optional, Dict, Any
from pathlib import Path
import json
from functools import lru_cache
from fastapi import Request
import logging

from app.core.context import get_current_request

logger = logging.getLogger(__name__)


class Language(str, Enum):
    """支持的语言类型"""

    ZH_CN = "zh-CN"
    EN_US = "en-US"


class I18nError(Exception):
    """国际化相关错误的基类"""

    pass


class TranslationNotFound(I18nError):
    """当翻译键不存在时抛出的异常"""

    pass


class TranslationFileNotFound(I18nError):
    """当翻译文件不存在时抛出的异常"""

    pass


def get_language(request: Optional[Request] = None, default: Language = Language.ZH_CN) -> Language:
    """
    根据请求信息获取当前语言

    优先级顺序:
    1. 查询参数 'lang'
    2. 请求头 'X-Language'
    3. 请求头 'Accept-Language'
    4. 默认语言

    参数:
        request: FastAPI请求对象
        default: 未指定语言时使用的默认语言

    返回:
        Language: 确定的语言类型
    """
    if not request:
        return default

    # 1. 查询参数
    lang = request.query_params.get("lang")
    if lang:
        try:
            return Language(lang)
        except ValueError:
            pass

    # 2. 自定义请求头
    lang = request.headers.get("X-Language")
    if lang:
        try:
            return Language(lang)
        except ValueError:
            pass

    # 3. Accept-Language请求头
    accept_language = request.headers.get("Accept-Language", "").lower()
    if accept_language.startswith("zh"):
        return Language.ZH_CN
    elif accept_language.startswith("en"):
        return Language.EN_US

    return default


@lru_cache(maxsize=2)
def load_translations(lang: Language) -> Dict[str, Any]:
    """
    加载并缓存指定语言的翻译文件
    """
    file_path = Path(__file__).parent / f"{lang.value}.json"
    try:
        with open(file_path, "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        raise TranslationFileNotFound(f"翻译文件不存在: {file_path}")
    except json.JSONDecodeError:
        raise I18nError(f"翻译文件JSON格式无效: {file_path}")


def get_nested_value(data: Dict[str, Any], key_path: str) -> str:
    """
    使用点号表示法获取嵌套字典中的值
    """
    current = data
    for key in key_path.split("."):
        if not isinstance(current, dict):
            logger.error(f"无效的路径: {key_path}")
            return key_path
        if key not in current:
            logger.error(f"翻译不存在: {key_path}")
            return key_path
        current = current[key]

    if not isinstance(current, str):
        logger.error(f"无效的翻译值: {key_path}")
        return key_path
    return current


def t(key: str, *args: Any, **kwargs: Any) -> str:
    """
    获取当前语言的翻译，支持参数格式化。如果翻译不存在，返回原始键并记录错误。

    example:
        >>> t("error.key_not_found", key="123")  # 翻译文本: "未找到键 {key}"
        "未找到键 123"
        >>> t("common.count", "苹果", 5)  # 翻译文本: "总共有 {} 个 {}"
        "总共有 5 个 苹果"
    """
    request = get_current_request()
    lang = get_language(request, Language.ZH_CN)

    try:
        translations = load_translations(lang)
        text = get_nested_value(translations, key)
        # 如果有提供格式化参数，则进行格式化
        if args or kwargs:
            try:
                return text.format(*args, **kwargs)
            except (KeyError, IndexError) as e:
                logger.error(f"格式化键 '{key}' 时出错: {str(e)}")
                return text
        return text
    except TranslationNotFound:
        return key
